#!/usr/bin/python2.4
#
# Copyright 2011 Google Inc. All Rights Reserved.

"""One-line documentation for windspeed module.

A detailed description of windspeed.
"""

__author__ = 'arb@google.com (Anthony Baxter)'

from BeautifulSoup import BeautifulSoup as BS
import csv
import cgi
import urllib

def scrape():
  stationloc = {}
  for i in csv.reader(open('qldstations.csv').read().split('\n')):
    if i: station, lat, lon = i
    stationloc[station] = (lat, lon)
  bs = BS(urllib.urlopen('http://www.bom.gov.au/qld/observations/qldall.shtml').read())
  stations = {}
  for t in bs.findAll('table', {'class': 'tabledata'}):
    body = t.find('tbody')
    for tr in body.findAll('tr'):
      i = tr.find('a')
      href = i['href']
      station = i.contents[0]
      tds = tr.findAll('td')
      latlon = stationloc[station]
      station_data = {'lat':latlon[0], 'lon':latlon[1], 'name': station}
      for td in tds:
        headers = td['headers'].split()
        interesting_hdr = headers[-2].split('-', 1)[1]
        station_data[interesting_hdr] = td.contents[0]
      stations[station] = station_data
  for station,data in stations.items():
    spd = data['wind-spd-kmh']
    if spd.strip() == "-":
      color = "small_white"
    else:
      spd = int(data['wind-spd-kmh'])
      color = "small_green"
      if spd > 50:
        color = "small_yellow"
      if spd > 80:
        color = "small_red"
    data['marker'] = color
    #print ",".join([station, data['lat'], data['lon'], data['datetime'],
                    #data['wind-dir'], data['wind-spd-kmh'],
                    #data['wind-gust-kmh'], color])

  return stations


#import ftclient
TABLE = "423240"

def updateTable(data):
  password = open("password.txt").read().strip()
  authtoken = ftclient.GoogleClientLogin('qldroadclosures@gmail.com', password)

  ft = ftclient.FTClient(authtoken)

  out = ft.runGetQuery("select rowid, Name from %s" % TABLE)

  input = csv.reader(out.split('\n'))

  existing = {}

  for line in input:
    if not line: continue
    rowid, name = line
    if rowid == 'rowid': continue
    existing[name] = rowid

  new = {}

  for station, data in data.items():
    query = """update %s
    SET wind_speed_kmh = '%s',
    wind_gust_kmh = '%s',
    marker = '%s',
    wind_direction = '%s',
    date = '%s'
    where ROWID = '%s'
    """ % (TABLE,
           data['wind-spd-kmh'],
           data['wind-gust-kmh'],
           data['marker'],
           data['wind-dir'],
           data['datetime'],
           existing[station])
    print query
    ft.runGetQuery(query)


# HERE BE DRAGONS
# TODO(jmcgill): Replace with Fusion Tables when we have time to play with OAuth
# and verify that upload/drop is reliable.
def makeStyle(document, image, id):
  text = """<Style id="%s">
    <BalloonStyle>
      <text>$[description]</text>
    </BalloonStyle>
    <IconStyle>
      <Icon>
        <href>%s</href>
      </Icon>
    </IconStyle>
  </Style>
  """ % (id, image)
  document.append(text)

def levelToStyle(level):
  # jmcgill, best coder, or bestEST coder?
  return '#' + level

Z_ORDERS = {
  'small_white': 0,
  'small_green': 30,
  'small_yellow': 40,
  'small_red': 50,
}

def levelToZOrder(cls):
  if cls not in Z_ORDERS:
    return 0
  else:
    return Z_ORDERS[cls]

def makePoint(document, point):
  style = levelToStyle(point['marker'])
  zOrder = levelToZOrder(point['marker'])
  desc = """<div>Station: <b>%s</b><br>
  Last updated: <b>%s</b><br>
  Wind speed: %s<br>
  Wind gust: %s<br>
  Wind direction: %s<br>
  Data from <a href="http://www.bom.gov.au/qld/observations/qldall.shtml">Bureau of Meteorology</a>
  </div>""" %(point['name'],
              point['datetime'],
              point['wind-spd-kmh'],
              point['wind-gust-kmh'], 
              point['wind-dir'],)
  text = """<Placemark>
    <styleUrl>%s</styleUrl>
    <name>%s</name>
    <description>%s</description>
    <Point>
      <coordinates>%s,%s,%s</coordinates>
    </Point>
  </Placemark>""" % (style, point['name'], cgi.escape(desc),
                     point['lon'], point['lat'], zOrder)
  document.append(text)

def makeKml(data):
  # Why bother with the DOM when you can concat strings?
  document = []
  document.append("""<?xml version="1.0" encoding="utf-8"?>
  <kml xmlns="http://earth.google.com/kml/2.0">
  <Document><name>Queensland Wind Measurements</name>""")

  # Create icon styles.
  base = "http://mapvisage.appspot.com/static/floodmap/images/wind/"
  makeStyle(document, base + "red.png", "small_red")
  makeStyle(document, base + "green.png", "small_green")
  makeStyle(document, base + "yellow.png", "small_yellow")
  makeStyle(document, base + "black.png", "small_black")
  makeStyle(document, base + "white.png", "small_white")

  # Add points - TODO(jmcgill) Infowindows?
  for point in data.values():
    makePoint(document, point)

  document.append("</Document></kml>")
  return "".join(document)


import controllers

def updateMap():
  from google.appengine.api import memcache
  data = scrape()
  kml = makeKml(data)
  memcache.set('qldwind', kml)

def showMap():
  from google.appengine.api import memcache
  return memcache.get('qldwind')

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class UpdatePage(webapp.RequestHandler):
  def get(self):
    updateMap()
    self.response.headers['Content-Type'] = 'text/plain'
    self.response.out.write('OK')

class ShowPage(webapp.RequestHandler):
  def get(self):
    controllers.cached_response(self.response, duration=300)
    self.response.headers['Content-Type'] = 'application/vnd.google-earth.kml+xml'
    self.response.out.write(showMap())

application = webapp.WSGIApplication([('/qldwind/update__', UpdatePage),
                                      ('/qldwind/kml', ShowPage)], debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()
